package AIColorUSAStates;

import java.util.ArrayList;
import java.util.Random;

public class Node implements Comparable<Node> {
	
	/**
	 * Color have four values. 1,2,3,4 stands for four differnet colors.
	 */
	public byte Color;
	
	/**
	 * Neighbours contain Nodes that connected with this one.
	 */
	private ArrayList<Node> Neighbours; 
	
	public String Name;
	
	public Node(byte color)
	{
		this.Color = color;
		this.Neighbours = new ArrayList<Node>();
	}
	
	public void setNewNeighbour(Node neiNode)
	{
		this.Neighbours.add(neiNode);
	}
	
	public ArrayList<Node> getNeighbours()
	{
		return this.Neighbours;
	}
	
	public int getNeigSize()
	{
		return this.Neighbours.size();
	}
	
	/**
	 * Calculate the collisions for this node
	 */
	public int getCollisions()
	{
		int collisionCounter = 0;
		for (Node neiNode : this.Neighbours) 
		{
			if (neiNode.Color == this.Color)
			{
				collisionCounter++;
			}
		}
		
		return collisionCounter;
	}
	
	/**
	 * Gets a random color
	 * @return
	 */
	public static byte getRandomColor()
	{
		Random ran = new Random();
		return (byte) (ran.nextInt(3) + 1) ;
	}
	
	/**
	 * Returns the color with a minimum collisions
	 * @return
	 */
	public byte getColorWithMinimumCollisionen()
	{
		int minCollisions = this.getCollisions();
		ArrayList<Byte> colorsWithMinCollisionen = new ArrayList<Byte>();
		
		for (int i = 1; i < 5; i++) 
		{
			this.Color = (byte) i;
			
			if (this.getCollisions() < minCollisions)
			{
				minCollisions = this.getCollisions();
			}
		}
		
		for (int i = 1; i < 5; i++) 
		{
			this.Color = (byte) i;
			if (this.getCollisions() == minCollisions)
			{
				colorsWithMinCollisionen.add((byte) i);
			}
		}
		
		// Is colorsWithMinCollisionen empty => current color had already the color with min collisions
		if (colorsWithMinCollisionen.size() == 0)
		{
			return this.Color;
		}
		
		// Exists more than one color with minimum collisions, take one by random
		Random ran = new Random();
		return colorsWithMinCollisionen.get(ran.nextInt(colorsWithMinCollisionen.size()));
	}

	@Override
	public int compareTo(Node other) {
		int oCollisions = other.getCollisions();
		int tCollisions = this.getCollisions();
				
		if (oCollisions == tCollisions)
			return 0;
		
		if (oCollisions > tCollisions)
			return 1;
		
		return -1;
	}
	
	@Override
	public boolean equals(Object other)
	{
		if (other.getClass() == String.class && other.toString().equals(this.Name))
		{
			return true;
		}
		
		
		if (other.getClass() != this.getClass())
		{
			return false;
		}
		
		Node oNode = (Node) other;
		if (oNode.Name.equals(this.Name))
		{
			return true;
		}
		return false;
	}
	
	@Override
	public String toString()
	{
		return this.Name;
	}
}
